.TH SG_WRITE_X "8" "May 2023" "sg3_utils\-1.48" SG3_UTILS
.SH NAME
sg_write_x \- SCSI WRITE normal/ATOMIC/SAME/SCATTERED/STREAM, ORWRITE commands
.SH SYNOPSIS
.B sg_write_x
[\fI\-\-16\fR] [\fI\-\-32\fR] [\fI\-\-app\-tag=AT\fR] [\fI\-\-atomic=AB\fR]
[\fI\-\-bmop=OP,PGP\fR] [\fI\-\-bs=BS\fR] [\fI\-\-combined=DOF\fR]
[\fI\-\-dld=DLD\fR] [\fI\-\-dpo\fR] [\fI\-\-dry\-run\fR] [\fI\-\-fua\fR]
[\fI\-\-generation=EOG,NOG\fR] [\fI\-\-grpnum=GN\fR] [\fI\-\-help\fR]
\fI\-\-in=IF\fR [\fI\-\-lba=LBA[,LBA...]\fR] [\fI\-\-normal\fR]
[\fI\-\-num=NUM[,NUM...]\fR] [\fI\-\-offset=OFF[,DLEN]\fR] [\fI\-\-or\fR]
[\fI\-\-quiet\fR] [\fI\-\-ref\-tag=RT\fR] [\fI\-\-same=NDOB\fR]
[\fI\-\-scat\-file=SF\fR] [\fI\-\-scat\-raw\fR] [\fI\-\-scattered=RD\fR]
[\fI\-\-stream=ID\fR] [\fI\-\-strict\fR] [\fI\-\-tag\-mask=TM\fR]
[\fI\-\-timeout=TO\fR] [\fI\-\-unmap=U_A\fR] [\fI\-\-verbose\fR]
[\fI\-\-version\fR] [\fI\-\-wrprotect=WPR\fR] \fIDEVICE\fR
.PP
Synopsis per supported command:
.PP
.B sg_write_x
\fI\-\-normal\fR \fI\-\-in=IF\fR [\fI\-\-16\fR] [\fI\-\-32\fR]
[\fI\-\-app\-tag=AT\fR] [\fI\-\-bs=BS\fR] [\fI\-\-dld=DLD\fR] [\fI\-\-dpo\fR]
[\fI\-\-fua\fR] [\fI\-\-grpnum=GN\fR] [\fI\-\-lba=LBA\fR] [\fI\-\-num=NUM\fR]
[\fI\-\-offset=OFF[,DLEN]\fR] [\fI\-\-ref\-tag=RT\fR] [\fI\-\-strict\fR]
[\fI\-\-tag\-mask=TM\fR] [\fI\-\-timeout=TO\fR] [\fI\-\-wrprotect=WPR\fR]
\fIDEVICE\fR
.PP
.B sg_write_x
\fI\-\-or\fR \fI\-\-in=IF\fR [\fI\-\-16\fR] [\fI\-\-32\fR]
[\fI\-\-bmop=OP,PGP\fR] [\fI\-\-bs=BS\fR] [\fI\-\-dpo\fR] [\fI\-\-fua\fR]
[\fI\-\-generation=EOG,NOG\fR] [\fI\-\-grpnum=GN\fR] [\fI\-\-lba=LBA\fR]
[\fI\-\-num=NUM\fR] [\fI\-\-offset=OFF[,DLEN]\fR] [\fI\-\-strict\fR]
[\fI\-\-timeout=TO\fR] [\fI\-\-wrprotect=OPR\fR] \fIDEVICE\fR
.PP
.B sg_write_x
\fI\-\-atomic=AB\fR \fI\-\-in=IF\fR [\fI\-\-16\fR] [\fI\-\-32\fR]
[\fI\-\-app-tag=AT\fR] [\fI\-\-bs=BS\fR] [\fI\-\-dpo\fR] [\fI\-\-fua\fR]
[\fI\-\-grpnum=GN\fR] [\fI\-\-lba=LBA\fR] [\fI\-\-num=NUM\fR]
[\fI\-\-offset=OFF[,DLEN]\fR] [\fI\-\-ref\-tag=RT\fR] [\fI\-\-strict\fR]
[\fI\-\-timeout=TO\fR] [\fI\-\-wrprotect=WPR\fR] \fIDEVICE\fR
.PP
.B sg_write_x
\fI\-\-same=NDOB\fR [\fI\-\-16\fR] [\fI\-\-32\fR] [\fI\-\-app-tag=AT\fR]
[\fI\-\-bs=BS\fR] [\fI\-\-dpo\fR] [\fI\-\-fua\fR] [\fI\-\-grpnum=GN\fR]
[\fI\-\-in=IF\fR] [\fI\-\-lba=LBA\fR] [\fI\-\-num=NUM\fR]
[\fI\-\-offset=OFF[,DLEN]\fR] [\fI\-\-ref\-tag=RT\fR] [\fI\-\-strict\fR]
[\fI\-\-timeout=TO\fR] [\fI\-\-unmap=U_A\fR]
[\fI\-\-wrprotect=WPR\fR] \fIDEVICE\fR
.PP
.B sg_write_x
\fI\-\-scattered=RD\fR \fI\-\-in=IF\fR [\fI\-\-16\fR] [\fI\-\-32\fR]
[\fI\-\-app-tag=AT\fR] [\fI\-\-bs=BS\fR] [\fI\-\-dld=DLD\fR] [\fI\-\-dpo\fR]
[\fI\-\-fua\fR] [\fI\-\-grpnum=GN\fR] [\fI\-\-lba=LBA[,LBA...]\fR]
[\fI\-\-num=NUM[,NUM...]\fR] [\fI\-\-offset=OFF[,DLEN]\fR]
[\fI\-\-ref\-tag=RT\fR] [\fI\-\-scat\-file=SF\fR] [\fI\-\-scat\-raw\fR]
[\fI\-\-strict\fR] [\fI\-\-tag\-mask=TM\fR] [\fI\-\-timeout=TO\fR]
[\fI\-\-wrprotect=WPR\fR] \fIDEVICE\fR
.PP
.B sg_write_x
\fI\-\-stream=ID\fR \fI\-\-in=IF\fR [\fI\-\-16\fR] [\fI\-\-32\fR]
[\fI\-\-app-tag=AT\fR] [\fI\-\-bs=BS\fR] [\fI\-\-dpo\fR] [\fI\-\-fua\fR]
[\fI\-\-grpnum=GN\fR] [\fI\-\-lba=LBA\fR] [\fI\-\-num=NUM\fR]
[\fI\-\-offset=OFF[,DLEN]\fR] [\fI\-\-ref\-tag=RT\fR] [\fI\-\-strict\fR]
[\fI\-\-tag\-mask=TM\fR] [\fI\-\-timeout=TO\fR] [\fI\-\-wrprotect=WPR\fR]
\fIDEVICE\fR
.SH DESCRIPTION
.\" Add any additional description here
This utility will send one of six SCSI commands, all associated with writing
data to the given \fIDEVICE\fR. They are a "normal" WRITE, ORWRITE, WRITE
ATOMIC, WRITE SAME, WRITE SCATTERED or WRITE STREAM. This utility supports
the 16 and 32 byte variants of all six commands. Hence some closely related
commands are not supported (e.g. WRITE(10)). All 32 byte variants, apart from
ORWRITE(32), require the \fIDEVICE\fR to be formatted with type 1, 2 or 3
Protection Information (PI), making all logical blocks 8 bytes (or a multiple
of 8 bytes) longer on the media.
.PP
The command line interface is a little crowded with over thirty options. Hence
the SYNOPSIS, after listing all the (long) options, lists those applicable
to each supported command. For each command synopsis, the option that selects
the SCSI command is shown first followed by any required options. If no
command option is given then a "normal" WRITE is assumed. Even though the
\fI\-\-scat\-file=SF\fR option can be given for every command, it is only
shown for WRITE SCATTERED where it is most useful. If the
\fI\-\-scat\-file=SF\fR option is given then neither the
\fI\-\-lba=LBA[,LBA...]\fR nor the \fI\-\-num=NUM[,NUM...]\fR options
should be given. Only the first item of the \fI\-\-lba=LBA[,LBA...]\fR and
the \fI\-\-num=NUM[,NUM...]\fR options (or first pair (or quintet) from the
\fI\-\-scat\-file=SF\fR option) is used for all but the WRITE SCATTERED
command. All commands can take \fI\-\-dry\-run\fR and \fI\-\-verbose\fR in
addition to those shown in the SYNOPSIS.
.PP
The logical block size in bytes can be given explicitly with the
\fI\-\-bs=BS\fR option, as long as \fIBS\fR is greater than zero. It
is typically a power of two, 512 or greater. If the \fI\-\-bs=BS\fR option
is not given or \fIBS\fR is zero then the SCSI READ CAPACITY command is
used to find the logical block size. First the READ CAPACITY(16) command is
tried and if successful the logical block size in the response is typically
used as the actual block size for this utility. The exception is when
PROT_EN is set in the response and the \fI\-\-wrprotect=WPR\fR option is
given and non\-zero; in which case 8 (bytes) is added to the logical block
size to yield the actual block size used by this utility. If READ
CAPACITY(16) fails then READ CAPACITY(10) is tried and if that works then
the logical block size in the response is used as the actual block size.
.PP
The number of bytes this utility will attempt to read from the file named by
\fIIF\fR is the product of the actual block size and the
number_of_blocks (\fINUM\fR or the sum of \fINUM\fR arguments). If less bytes
are read from the file \fIIF\fR and the \fI\-\-strict\fR option is given then
this utility exits with an exit status of SG_LIB_FILE_ERROR. If less bytes
are read from the file \fIIF\fR and the \fI\-\-strict\fR option is not
given then bytes of zero are substituted for the "missing" bytes and this
utility continues.
.PP
Attempts to write multi megabyte data with a single command are likely to fail
for one of several reasons. First the operating system might object to
allocating a buffer that large. Next the SCSI pass\-through usually limits
data blocks to a few megabytes or less. Finally the storage device might
have a limited amount of RAM to support a write operation such as atomic (as
it may need to roll back). The storage device can inform the application
client of its limitations via the block limits VPD page (0xb0), with the
maximum atomic transfer length field amongst others.
.PP
A degenerate LBA (Logical Block Address) range descriptor with no PI has
an LBA and NUM of zero. A degenerate LBA range descriptor with PI
additionally has its RT, AT and TM fields set to zero (note: that is not
the default values for RT, AT and TM). They are degenerate in the sense
that they are indistinguishable from a pad of zeros that follow the scatter
list in the data\-out buffer. SBC\-4 makes clear that a degenerate LBA
range descriptor is valid. This may become an issue if \fIRD\fR given in the
\fI\-\-scattered=RD\fR option has the value 0. In this case the logic may
need to scan the user provided data to calculate the number of LBA
range descriptors which is required by the WRITE SCATTERED cdb. In the
absence of other information the logic will take a degenerate LBA range
descriptor as a terminator of the scatter list.
.PP
The reference for these commands is SBC\-4 (T10/BSR INCITS 506\-2021)
and draft SBC\-5 INCITS 571 revision 1 dated 21 May 2021. All six SCSI
commands are described in those documents. WRITE ATOMIC was added in
SBC\-4 revision 3; WRITE STREAM was added in SBC\-4 revision 7; WRITE
SCATTERED was added in SBC\-4 revision 11 while the others are in the
previous SBC\-3 standard.
.SH OPTIONS
Arguments to long options are mandatory for short options as well.
The options are arranged in alphabetical order based on the long
option name.
.TP
\fB\-6\fR, \fB\-\-16\fR
send the 16 byte cdb variant of the selected SCSI command. If no command
is selected then the (normal) SCSI WRITE(16) command is sent. If neither
this option nor the \fI\-\-32\fR option is given then this option is
assumed.
.TP
\fB\-3\fR, \fB\-\-32\fR
send the 32 byte cdb variant of the selected SCSI command. If no command
is selected then the (normal) SCSI WRITE(32) command is sent. If neither
this option nor the \fI\-\-16\fR option is given then then the
\fI\-\-16\fR option is assumed. If both this option and the \fI\-\-16\fR
option are given then this option takes precedence. Note that apart
from ORWRITE(32) all other 32 byte cdb variants require a \fIDEVICE\fR
formatted with type 1, 2 or 3 protection information.
.TP
\fB\-a\fR, \fB\-\-app\-tag\fR=\fIAT\fR
where \fIAT\fR is the "expected logical block application tag" field found in
most of the 32 byte cdb variants (the exception is ORWRITE(32)). \fIAT\fR is
a 16 bit field which means the maximum value is 0xffff. The default value
is 0xffff .
.TP
\fB\-A\fR, \fB\-\-atomic\fR=\fIAB\fR
selects the WRITE ATOMIC command and \fIAB\fR is placed in the Atomic
Boundary field of its cdb. It is a 16 bit field so the maximum value
is 0xffff. If unsure what value to set, try 0 which will attempt to
write the whole data\-out buffer in a single atomic operation.
.TP
\fB\-B\fR, \fB\-\-bmop\fR=\fIOP,PGP\fR
where \fIOP\fR and \fIPGP\fR are the values to be placed in ORWRITE(32)'s
BMOP and 'Previous Generation Processing' fields respectively. BMOP is
a 3 bit field (ranges from 0 to 7) and PGP is a 4 bit field (ranges from
0 to 15). Both fields default to 0.
.TP
\fB\-b\fR, \fB\-\-bs\fR=\fIBS\fR
where \fIBS\fR is the logical block size or the actual block size which
will be slightly bigger. The default value is zero. If this option
is not given or is given with a \fIBS\fR of zero then the SCSI READ
CAPACITY(16) command is sent to \fIDEVICE\fR. If that fails then the READ
CAPACITY(10) command is sent. The logical and actual block size will be
derived from the response of the READ CAPACITY command.
.br
This section assumes \fIBS\fR is greater than zero. If \fIBS\fR is less than
512 (bytes) or not a multiple of 8, a warning is issued and the utility
continues unless the \fI\-\-strict\fR option is also given. If \fIBS\fR
is a power of two (e.g. 512) then the logical and actual block size is
set to \fIBS\fR (e.g. 512). If \fIBS\fR is not a power of two (e.g. 520)
then the logical block size is set to the closest power of two less than
\fIBS\fR (e.g. 512) and the actual block size is set to \fIBS\fR (e.g.
520).
.br
If the logical and actual block size are different then a later check
will reduce the actual block size back to the logical block size unless
\fI\-\-wrprotect=WPR\fR is greater than zero.
.TP
\fB\-c\fR, \fB\-\-combined\fR=\fIDOF\fR
This option only applies to WRITE SCATTERED and assumes the whole data\-out
buffer can be read from \fIIF\fR given by the \fI\-\-in=IF\fR option. The
whole data\-out buffer is the parameter list header, followed by zero or more
LBA range descriptors, optionally followed by some pad bytes and then the
data to be written to the media. If the \fI\-\-lba=LBA[,LBA...]\fR,
\fI\-\-num=NUM[,NUM...]\fR or \fI\-\-scat\-file=SF\fR options are also given
then an error is generated. The \fIDOF\fR argument should be the value
suitable for the 'Logical Block Data Offset' field in the WRITE SCATTERED
cdb. This is the offset in the data\-out buffer where the data to write
to the media commences. The unit of that field is the actual block size
which is the logical block size plus a multiple of 8, if protection
information (PI) is being sent. When \fIWPR\fR (from \fI\-\-wrprotect=WPR\fR)
is greater than zero then PI is expected. SBC\-4 revision 15 does not state
it but it would appear that a \fIDOF\fR value of 0 is invalid. It is
suggested that this option be used with the \fI\-\-strict\fR option while
experimenting as random or incorrect data fed in via the \fI\-\-in=IF\fR
option could write a lot of "interesting" data all over the \fIDEVICE\fR.
If \fIDOF\fR is given as 0 the utility will scan the data in \fIIF\fR until
\fIRD\fR LBA range descriptors are found; or if \fIRD\fR is also 0 until a
degenerate LBA range descriptor is found.
.TP
\fB\-D\fR, \fB\-\-dld\fR=\fIDLD\fR
where \fIDLD\fR is the duration limits descriptor spread across 3 bits in
the SCSI WRITE(16) and the WRITE SCATTERED(16) cdbs. \fIDLD\fR is between 0
to 7 inclusive with a default of zero. The DLD0 field in WRITE(16) and WRITE
SCATTERED(16) is set if (0x1 & \fIDLD\fR) is non\-zero. The DLD1 field in
both cdbs is set if (0x2 & \fIDLD\fR) is non\-zero. The DLD2 field in both
cdbs is set if (0x4 & \fIDLD\fR) is non\-zero.
.TP
\fB\-d\fR, \fB\-\-dpo\fR
if this option is given then the DPO (disable page out) bit field in the
cdb is set. The default is to clear this bit field. Applies to all
commands supported by thus utility except WRITE SAME.
.TP
\fB\-x\fR, \fB\-\-dry\-run\fR
this option exits (with a status of 0) just before it would otherwise send
the selected SCSI write command. It may still send a SCSI READ CAPACITY
command (16 byte variant and perhaps 10 byte variant as well) so the
\fIDEVICE\fR is still required. It reads the data in and processes it if the
\fI\-\-in=IF\fR and/or the \fI\-\-scat\-file=SF\fR options are given. All
command line processing and sanity checks (e.g. if the \fI\-\-strict\fR
option is given) will be performed and if there is an error then there will
be a non zero exit status value.
.br
If this option is given twice (e.g. \-xx) then instead of performing the
selected write SCSI command, the data\-out buffer is written to a file
called sg_write_x.bin . If it doesn't exist then that file is created in
the current directory and is truncated if it previously did exist with
longer contents. The data\-out buffer is written in binary with some
information about it written to stdout. For writes other than scattered
the filename and its length in bytes is output to stdout. For write
scattered additionally its number of LBA range descriptors and its
logical block data offset written to stdout.
.TP
\fB\-f\fR, \fB\-\-fua\fR
if this option is given then the FUA (force unit access) bit field in the
cdb is set. The default is to clear this bit field. Applies to all
commands supported by thus utility except WRITE SAME.
.TP
\fB\-G\fR, \fB\-\-generation\fR=\fIEOG,NOG\fR
the arguments for this option are used by the ORWITE(32) command only.
\fIEOG\fR is placed in the "Expected ORWgeneration" field while \fINOG\fR
is placed in the "New ORWgeneration" field. Both are 32 bits long and
default to zero.
.TP
\fB\-g\fR, \fB\-\-grpnum\fR=\fIGN\fR
sets the 'Group number' field to \fIGN\fR. Defaults to a value of zero.
\fIGN\fR should be a value between 0 and 63.
.TP
\fB\-h\fR, \fB\-\-help\fR
output the usage message then exit. Use multiple times for more help.
Currently '\-h' to '\-hhhh' provide different output.
.TP
\fB\-i\fR, \fB\-\-in\fR=\fIIF\fR
read data (in binary) from a file named \fIIF\fR in a single OS system
call (in Unix: read(2)). That data is placed in a continuous buffer and then
used as the data\-out buffer for all SCSI write commands apart from WRITE
SCATTERED(16 or 32) which may include other data in the data\-out buffer.
For WRITE SCATTERED (16 or 32) the data\-out buffer is made up of 3 or 4
components in this order: a parameter list header (32 zero bytes); zero or
more LBA range descriptors, optionally some pad bytes (zeros) and then data
to write to the media. For WRITE SCATTERED \fIIF\fR only provides the data
to write to the media unless \fI\-\-combined=DOF\fR is given. When the
\fI\-\-combined=DOF\fR option is given \fIIF\fR contains all components of
the WRITE SCATTERED data\-out buffer in binary. The data read from \fIIF\fR
starts from byte offset \fIOFF\fR which defaults to zero and no more than
\fIDLEN\fR bytes are read from that point (i.e. from the file byte offset
\fIOFF\fR). If \fIDLEN\fR is zero or not given the rest of the file \fIIF\fR
is read. This option is mandatory apart from when \-\-same=1 is given (that
sets the NDOB bit which stands for "No Data Out Buffer"). In Unix based
OSes, any number of zeros can be produced by using the /dev/zero device file.
.br
\fIIF\fR may be "\-" which is taken as stdin. In this case the
\fI\-\-offset=OFF,DLEN\fR can be given with \fIOFF\fR set to 0 and
\fILEN\fR set to a non\-zero value, preferably a multiple of the actual block
size. The utility can also deduce how long the \fIIF\fR should be from
\fINUM\fR (or the sum of them in the case of a scatter list).
.TP
\fB\-l\fR, \fB\-\-lba\fR=\fILBA[,LBA...]\fR
where the argument is a single Logical Block Address (LBA) or a comma
separated list of \fILBA\fRs each of which is the address of the first block
written by the selected write command. Only the WRITE SCATTERED command
can usefully take more than one \fILBA\fR. Whatever number of \fILBA\fRs is
given, there needs to be an equal number of \fINUM\fRs given to the
\fI\-\-num=NUM[,NUM...]\fR option. The first given \fILBA\fR joins with the
first given \fINUM\fR to form the first LBA range descriptor (which T10
number from zero in SBC\-4). The second \fILBA\fR joins with the second
\fILBA\fR to form the second LBA range descriptor, etc. A more convenient
way to define a large number of LBA range descriptors is with the
\fI\-\-scat\-file=SF\fR option. Defaults to logical block 0 (which could be
dangerous) while \fINUM\fR defaults to 0 which makes the combination harmless.
\fILBA\fR is assumed to be in decimal unless prefixed with '0x' or has a
trailing 'h'.
.TP
\fB\-N\fR, \fB\-\-normal\fR
the choice of a "normal" WRITE (16 or 32) command can be made explicitly
with this option. In the absence of selecting any other command (e.g.
\fI\-\-atomic=AB\fR ), the choice of a "normal" WRITE is the default.
.TP
\fB\-n\fR, \fB\-\-num\fR=\fINUM[,NUM...]\fR
where the argument is a single NUMber of blocks (NUM) or a comma separated
list of \fINUM\fRs that pair with the corresponding entries in the
\fI\-\-lba=LBA[,LBA...]\fR option. If a \fINUM\fR is given and is not
provided by another method (e.g. by using the \fI\-\-scat\-file=SF\fR option)
then it defaults to the number of blocks derived from the size of the file
named by \fIIF\fR (starting at byte offset \fIOFF\fR to the end or the file
or \fIDLEN\fR). Apart from the \fI\-\-combined=DOF\fR option, an LBA must
be explicitly given (either with \fII\-\-lba=LBA\fR or via
\fI\-\-scat\-file=SF\fR), if not \fINUM\fR defaults to 0 as a safety measure.
.TP
\fB\-o\fR, \fB\-\-offset\fR=\fIOFF[,DLEN]\fR
where \fIOFF\fR is the byte offset within the file named \fIIF\fR to start
reading from. The default value of \fIOFF\fR is zero which is the beginning
of file named \fIIF\fR. \fIDLEN\fR is the maximum number of bytes to read,
starting at byte offset \fIOFF\fR, from the file named \fIIF\fR. Less bytes
will be read if an end of file occurs before \fIDLEN\fR is exhausted. If
\fIDLEN\fR is zero or not given then reading from byte offset \fIOFF\fR to
the end of the file named \fIIF\fR is assumed.
.TP
\fB\-O\fR, \fB\-\-or\fR
selects the ORWRITE command. ORWRITE(16) has similar fields to WRITE(16)
apart from the WRPROTECT field being named ORPROTECT with slightly different
semantics and the absence of the 3 DLD bit fields. ORWRITE(32) has four
extra fields that are set with the \fI\-\-bmop=OP,PGP\fR and
\fI\-\-generation=EOG,NOG\fR options. ORWRITE(32) is the only 32 byte cdb
command in this utility that does not require a \fIDEVICE\fR formatted with
type 1, 2 or 3 PI (although it will still work if it is formatted with PI).
.TP
\fB\-Q\fR, \fB\-\-quiet\fR
suppress some informational messages such as the ones associated with
detected errors when this utility is about to exit. The exit status value
is still returned to the operating system when this utility exits.
.TP
\fB\-r\fR, \fB\-\-ref\-tag\fR=\fIRT\fR
where \fIRT\fR is the "expected initial logical block reference tag" field
found in the 32 byte cdb variants of WRITE, WRITE ATOMIC, WRITE SAME and
WRITE STREAM.  The field is also found in the WRITE SCATTERED(32) LBA range
descriptors. It is a 32 bit field which means the maximum value is
0xffffffff. The default value is 0xffffffff.
.TP
\fB\-S\fR, \fB\-\-same\fR=\fINDOB\fR
selects the WRITE SAME command with the NDOB field set to \fINDOB\fR which
stands for No Data\-Out Buffer. \fINDOB\fR can take values 0 or 1 (i.e. it
is a single bit field). When \-\-same=1 all options associated with the
data\-out buffer are ignored.
.TP
\fB\-q\fR, \fB\-\-scat\-file\fR=\fISF\fR
where \fISF\fR is the name of an auxiliary file containing the scatter list
for the WRITE SCATTERED command. If the \fI\-\-scat\-raw\fR option is also
given then \fISF\fR is assumed to contain both the parameter list header (32
bytes of zeros) followed by zero or more LBA range descriptors which are
also 32 bytes long each. These components are as defined by SBC\-4 (i.e.
in binary with integers in big endian format). If the \fI\-\-scat\-raw\fR
option is not given then a file of ACSII hexadecimal is expected as described
in the SCATTERED FILE ASCII FORMAT section below.
.br
If this option is given with the \fI\-\-combined=DOF\fR option then this
utility will exit with a syntax error. \fISF\fR must not be "\-", a way
of stopping the user trying to redirect stdin.
.TP
\fB\-R\fR, \fB\-\-scat\-raw\fR
this option only effects the way that the file named \fISF\fR from the
\fI\-\-scat\-file=SF\fR option for WRITE SCATTERED is interpreted. By
default (i.e. without this option), \fISF\fR is parsed as ASCII hexadecimal
with blank lines and line contents from and including '#' to the end of
line ignored. Hence it can contain comments and other indications. When
this option is given, the file named \fISF\fR is interpreted as binary.
As binary it is assumed to contain 32 bytes of zeros (the WRITE SCATTERED
parameter list header) followed by zero or more LBA range descriptors (which
are 32 bytes each). If the \fI\-\-strict\fR option is given the reserved
field in those two items are checked with any non zero bytes causing an
error.
.TP
\fB\-S\fR, \fB\-\-scattered\fR=\fIRD\fR
selects the WRITE SCATTERED command with \fIRD\fR being the number of LBA
range descriptors that will be placed in the data\-out buffer. If \fIRD\fR
is zero then the logic will try and determine the number of range descriptors
by other means (e.g. by parsing the file named by \fISF\fR, if there is one).
The LBA range descriptors differ between the 16 and 32 byte cdb variants of
WRITE SCATTERED. In the 16 byte cdb variant the 32 byte LBA range descriptor
is made up of an 8 byte LBA, followed by a 4 byte number_of_blocks followed
by 20 bytes of zeros. In the 32 byte variant the LBA and number_of_blocks
are followed by a RT (4 bytes), an AT (2 bytes) and a TM (2 bytes) then
12 bytes of zeros.
.br
This paragraph applies when \fIRD\fR is greater than zero.
If \fIRD\fR is less than the number of LBA range descriptors built from
command line options, from the \fI\-\-scat\-file=SF\fR option or
decoded from \fIIF\fR (when the \fI\-\-combined=DOF\fR option is given)
then \fIRD\fR takes precedence; so \fIRD\fR is placed in the "Number of
LBA Range Descriptors" field in the cdb. If \fIRD\fR is greater than
the number of LBA range descriptors found from the provided data and
options, then an error is generated.
.TP
\fB\-T\fR, \fB\-\-stream\fR=\fIID\fR
selects the WRITE STREAM command with the STR_ID field set to \fIID\fR.
\fIID\fR can take values from 0 to 0xffff (i.e. it is a 16 bit field).
.TP
\fB\-s\fR, \fB\-\-strict\fR
when this option is present, more things (e.g. that reserved fields contain
zeros) and any irregularities will terminate the utility with a message to
stderr and an indicative exit status. While experimenting with these commands,
especially WRITE SCATTERED, it is recommended to use this option.
.TP
\fB\-t\fR, \fB\-\-tag\-mask\fR=\fITM\fR
where \fITM\fR is the "logical block application tag mask" field  found in the
32 byte cdb variants of WRITE, WRITE ATOMIC, WRITE SAME and WRITE STREAM. The
field is also found in the WRITE SCATTERED(32) LBA range descriptors. It is a
16 bit field which means the maximum value is 0xffff. The default value is
0xffff.
.TP
\fB\-I\fR, \fB\-\-timeout\fR=\fITO\fR
where \fITO\fR is the command timeout value in seconds. The default value is
120 seconds. If \fINUM\fR is large on slow media then these WRITE commands
may require considerably more time than 120 seconds to complete. An alternate
long option form is \fI\-\-tmo=TO\fR .
.TP
\fB\-u\fR, \fB\-\-unmap\fR=\fIU_A\fR
where \fIU_A\fR is OR\-ed bit values used to set the UNMAP and ANCHOR bit
fields in the WRITE SAME (16 or 32) cdb. If \fIU_A\fR is 1 then the UNMAP
bit field is set; if \fIU_A\fR is 2 then the ANCHOR bit field is set; if
\fIU_A\fR is 3 then both the UNMAP and ANCHOR bit fields are set. The
default value for both bit fields is clear (0); setting \fIU_A\fR to 0 will
also clear both bit fields.
.TP
\fB\-v\fR, \fB\-\-verbose\fR
increase the degree of verbosity (debug messages). These messages are usually
written to stderr.
.TP
\fB\-V\fR, \fB\-\-version\fR
output version string then exit.
.TP
\fB\-w\fR, \fB\-\-wrprotect\fR=\fIWPR\fR
sets the WRPROTECT field (3 bits) in all sg_write_x commands apart from
ORWRITE which has a 3 bit ORPROTECT field (and the synopsis shows \fIOPR\fR
to highlight the difference). In all cases \fIWPR\fR is placed
in that 3 bit field. The default value is zero which does not send any PI
in the data\-out buffer. \fIWPR\fR should be a value between 0 and 7.
.SH SCATTERED FILE ASCII FORMAT
All commands in this utility can take a \fI\-\-scat\-file=SF\fR and that
option can be seen as a replacement for the \fI\-\-lba=LBA[,LBA...]\fR and
\fI\-\-num=NUM[,NUM...]\fR options. if both the \fI\-\-scat\-file=SF\fR and
\fI\-\-scat\-raw\fR options are given then the file named \fISF\fR is
expected to be binary and contain the parameter list header (32 bytes of
zeros for both the 16 and 32 byte variants) followed by zero or more LBA
range descriptors, each of 32 bytes each. This section describes what is
expected in \fISF\fR when the \fI\-\-scat\-raw\fR option is not given.
.PP
The ASCII hexadecimal "scatter file" (named by \fISF\fR) can contain
comments, empty lines and numbers. If multiple numbers appear on one line
they can be separated by spaces, tabs or a single comma. Numbers are parsed
as decimal unless prefixed by "0x" (or "0X") or have a suffix of "h". Ox is
the prefix of hexadecimal number is the C language while T10 uses the "h"
suffix for the same purpose. Anything from and including a "#" character
to the end\-of\-line is ignored, so comments can be placed there.
.PP
For the WRITE SCATTERED (16) command, its LBA range descriptors contain two
items per descriptor: an 8 byte LBA followed by a 4 byte number_of_blocks.
The remaining 20 bytes of the descriptor are zeros. The format accepted
is relatively loose with each decoded value being placed in an LBA and
then a number_of_blocks until the end\-of\-file is reached. The pattern
starts with a LBA and if it doesn't finish with a number_of_blocks (i.e.
an odd number of values are parsed) an error occurs. So the number of
LBA range descriptors generated will be half the number of values parsed
in \fISF\fR.
.PP
For the WRITE SCATTERED (32) command, its LBA range descriptors contain five
items per descriptor: an 8 byte LBA followed by a 4 byte number_of_blocks,
then a 4 byte RT, a 2 byte AT, and a 2 byte TM. The last three items are
associated with protection information (PI). The accepted format in the
\fISF\fR file is more constrained than the 16 byte cdb variant. The items
for each LBA range descriptor must be found on one line with adjacent items
being comma separated. The first two items (LBA and number_of_blocks) must be
given, and if no more items are on the line then RT, AT and TM are given
their default values (all "ff" bytes). Spaces and tabs may appear between
items but commas are the separators. Two commas with no value between them
will cause the "missing" item to receive its default value.
.SH NOTES
Various numeric arguments (e.g. \fILBA\fR) may include multiplicative
suffixes or be given in hexadecimal. See the "NUMERIC ARGUMENTS" section
in the sg3_utils(8) man page.
.PP
In Linux, prior to lk 3.17, the sg driver did not support cdb sizes greater
than 16 bytes. Hence a device node like /dev/sg1 which is associated with
the sg driver would fail with this utility if the \fI\-\-32\fR option was
given (or implied by other options). The bsg driver with device nodes like
/dev/bsg/6:0:0:1 does support cdb sizes greater than 16 bytes since its
introduction in lk 2.6.28 .
.SH EXIT STATUS
The exit status of sg_write_x is 0 when it is successful. Otherwise see
the sg3_utils(8) man page.
.SH EXAMPLES
One simple usage is to write 4 blocks of zeros from (and including) a given
LBA according to the rules of WRITE ATOMIC with an atomic boundary of 0.
Since no cdb size option is given, the 16 byte cdb will be assumed (i.e.
WRITE ATOMIC(16)):
.PP
  sg_write_x \-\-atomic=0 \-\-in=/dev/zero \-\-lba=0x1234 \-\-num=4 /dev/sdc
.PP
Since \fI\-\-bs=BS\fR has not been given, then this utility will call the
READ CAPACITY(16) command on /dev/sdc to determine the number of bytes in a
logical block. If the READ CAPACITY(16) command fails then the READ
CAPACITY(10) command is tried. Let us assume one of them works and that
the number of bytes in each logical block is 512 bytes. So 4 blocks of
zeros (each block containing 512 bytes) will be written from (and including)
LBA 0x1234 . Now to bypass the need for the READ CAPACITY command(s) the
\fI\-\-bs=BS\fR option can be used:
.PP
  sg_write_x \-\-atomic=0 \-\-bs=512 \-\-in=/dev/zero \-\-lba=0x1234 \-\-num=4
/dev/sdc
.PP
Since \-\-bs= is given and its value (512) is a power of 2, then the actual
block size is also 512. If instead 520 was given then the logical block size
would be 512 (the highest power of 2 less than 520) and the actual block size
would be 520 bytes. To send the 32 byte variant add \-\-32 as in:
.PP
  sg_write_x \-\-atomic=0 \-\-32 \-\-bs=512 \-\-in=/dev/zero \-\-lba=0x1234
\-\-num=4 /dev/sdc
.PP
For examples using 'sg_write_x \-\-same=NDOB' see the manpage for
sg_write_same(8). The syntax is a little different but the semantics are the
same.
.PP
To send a WRITE STREAM(32) with a STR_ID of 1 use the following:
.PP
  sg_write_x \-\-stream=1 \-\-32 \-\-bs=512 \-\-in=/dev/zero \-\-lba=0x1234
\-\-num=4 /dev/sdc
.PP
Next is a WRITE SCATTERED(16) command with the scatter list, split between
the \-\-lba= and \-\-num= options, on the command line:
.PP
  sg_write_x  \-\-scattered=2 \-\-lba=2,0x33 \-\-num=4,1 -i /dev/zero /dev/sg1
.PP
Example of a WRITE SCATTERED(16) command with a degenerate LBA range
descriptor (first element to \-\-lba= and \-\-num=):
.PP
  sg_write_x  \-\-scattered=2 \-\-lba=0,0x33 \-\-num=0,1 -i /dev/zero /dev/sg1
.PP
Example of a WRITE SCATTERED(16) command with the scatter list in
scat_file.txt
.PP
  sg_write_x  \-\-scattered=3 \-q scat_file.txt \-i /dev/zero /dev/sg1
.PP
Next a WRITE SCATTERED(16) command with its scatter list and data in a
single file. Note that the argument to \-\-scattered= is 0 so the number of
LBA range descriptors is calculated by analyzing the first two blocks of
scat_data.bin (because the argument to \-\-combined= is 2) :
.PP
  sg_write_x  \-\-scattered=0 \-\-combined=2 \-i scat_data.bin /dev/sg1
.PP
When the \-xx option is used, a WRITE SCATTERED command is not executed
but instead the contents of the data\-out buffer are written to a file
called sg_write_x.bin . In the case of WRITE SCATTERED that binary file
is suitable for supplying to a later invocation to do the actual write
to media. For example:
.PP
  $ sg_write_x  \-\-scattered=3 \-q scat_file.txt \-xx \-i /dev/zero /dev/sg1
  Wrote 8192 bytes to sg_write_x.bin, LB data offset: 1
  Number of LBA range descriptors: 3
 
  sg_write_x  \-\-scattered=0 \-\-combined=1 \-i sg_write_x.bin /dev/sg1
.PP
Notice when the sg_write_x.bin is written (and nothing is written to the
media), a summary of what has happened is sent to stdout. The value shown
for "LB data offset:" (1) should be given to the \-\-combined= option
when the write to media actually occurs (i.e. the second invocation shown
directly above).
.SH AUTHORS
Written by Douglas Gilbert.
.SH "REPORTING BUGS"
Report bugs to <dgilbert at interlog dot com>.
.SH COPYRIGHT
Copyright \(co 2017\-2023 Douglas Gilbert
.br
This software is distributed under a BSD\-2\-Clause license. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
.SH "SEE ALSO"
.B sg_readcap,sg_vpd,sg_write_same,sg_stream_ctl(sg3_utils)
